﻿using DotNetty.Buffers;
using DotNetty.Transport.Channels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NetC100K;
using NetC100K.Setting;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NetC100KTest
{
    public class HostedService : IHostedService
    {
        private ILogger _logger;
        private SessionPool _sessionPool;
        private IConfiguration _configuration;

        public HostedService(SessionPool sessionPool, ILogger<HostedService> logger, IConfiguration configuration)
        {
            try
            {
                _logger = logger;
                _sessionPool = sessionPool;
                _configuration = configuration;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{DateTime.Now}:{ex.StackTrace},错误原因：{ ex.Message}");
            }
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            try
            {
                var serverSetting = _configuration.GetSection("Server").Get<ServerSetting>();
                if (serverSetting == null)
                {
                    throw new ArgumentNullException("配置文件server配置为空");
                }

                var clientSetting = _configuration.GetSection("Client").Get<ClientSetting>();
                if (clientSetting == null)
                {
                    throw new ArgumentNullException("配置文件client配置为空");
                }
                if (clientSetting.EachConcurrent < IPEndPoint.MinPort || clientSetting.EachConcurrent > IPEndPoint.MaxPort)
                {
                    throw new ArgumentNullException($"配置文件client并发数取值范围为：{IPEndPoint.MinPort}到{IPEndPoint.MaxPort}");
                }

                var ipList = clientSetting.IpList;
                for (int i = 0; i < ipList.Length; i++)
                {
                    for (int j = 1; j <= clientSetting.EachConcurrent; j++)
                    {
                        try
                        {
                            Task.Delay(1).Wait();
                            var localAddress = new IPEndPoint(IPAddress.Parse(ipList[i]), j);
                            var remoteAddress = new IPEndPoint(IPAddress.Parse(serverSetting.IP), serverSetting.Port);
                            _sessionPool.ConnectAsync(remoteAddress, localAddress);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "HostedService连接服务时发生错误：{0}", ex.Message);
                        }
                    }
                }

                //Task.Run(() => { AddSession(ipList, serverSetting, clientSetting); });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "HostedService开启时发生错误：{0}", ex.Message);
            }
            return Task.CompletedTask;
        }

        public void AddSession(string[] ipList, ServerSetting serverSetting, ClientSetting clientSetting)
        {
            while (true)
            {
                try
                {
                    for (int i = 0; i < ipList.Length; i++)
                    {
                        for (int j = 1; j <= clientSetting.EachConcurrent; j++)
                        {
                            try
                            {
                                var localAddress = new IPEndPoint(IPAddress.Parse(ipList[i]), j);
                                var remoteAddress = new IPEndPoint(IPAddress.Parse(serverSetting.IP), serverSetting.Port);
                                _sessionPool.ConnectAsync(remoteAddress, localAddress);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, "HostedService连接服务时发生错误：{0}", ex.Message);
                            }
                        }
                    }
                }
                catch (Exception ex) { }
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            try
            {
                if (_sessionPool != null && cancellationToken.IsCancellationRequested)
                {
                    return _sessionPool.Close();
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "HostedService关闭时发生错误：{0}", ex.Message);
            }
            return Task.CompletedTask;
        }
    }
}
